package org.sabayframework.mem.impl;

import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;

import org.sabayframework.mem.BigBuffer;

/**
 * Read-only buffer with 0-length capacity.
 * */
public final class EmptyBigBuffer implements BigBuffer {

	/** 
	 * Empty buffer singleton instance.
	 * */
	public static EmptyBigBuffer INSTANCE = new EmptyBigBuffer();
	
	private EmptyBigBuffer() {}
	
	@Override
	public int compareTo(BigBuffer o) {
		return (int)o.remaining();
	}

	@Override
	public long capacity() {
		return 0;
	}

	@Override
	public long position() {
		return 0;
	}

	@Override
	public BigBuffer position(long newPosition) {
		if(newPosition != 0)throw new IllegalArgumentException();
		return this;
	}

	@Override
	public long limit() {
		return 0;
	}

	@Override
	public BigBuffer limit(long newLimit) {
		if(newLimit != 0)throw new IllegalArgumentException();	
		return this;
	}

	@Override
	public BigBuffer clear() {
		return this;
	}

	@Override
	public BigBuffer flip() {
		return this;
	}

	@Override
	public BigBuffer rewind() {
		return this;
	}

	@Override
	public long remaining() {
		return 0;
	}

	@Override
	public boolean hasRemaining() {
		return false;
	}

	@Override
	public boolean isReadOnly() {
		return true;
	}

	@Override
	public boolean hasArray() {
		return false;
	}

	@Override
	public byte[] array() {
		throw new ReadOnlyBufferException();
	}

	@Override
	public int arrayOffset() {
		throw new ReadOnlyBufferException();
	}

	@Override
	public boolean isDirect() {
		return false;
	}

	@Override
	public ByteOrder order() {
		return ByteOrder.nativeOrder();
	}

	@Override
	public BigBuffer slice() {
		return this;
	}

	@Override
	public BigBuffer duplicate() {
		return this;
	}

	@Override
	public BigBuffer asReadOnlyBuffer() {
		return this;
	}

	@Override
	public BigBuffer compact() {
		throw new ReadOnlyBufferException();
	}

	@Override
	public byte get(long index) {
		throw new IndexOutOfBoundsException();
	}

	@Override
	public void put(long index, byte value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public char getChar(long index) {
		throw new IndexOutOfBoundsException();
	}

	@Override
	public void putChar(long index, char value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public short getShort(long index) {
		throw new IndexOutOfBoundsException();
	}

	@Override
	public void putShort(long index, short value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public int getInt(long index) {
		throw new IndexOutOfBoundsException();
	}

	@Override
	public void putInt(long index, int value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public float getFloat(long index) {
		throw new IndexOutOfBoundsException();
	}

	@Override
	public void putFloat(long index, float value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public long getLong(long index) {
		throw new IndexOutOfBoundsException();
	}

	@Override
	public void putLong(long index, long value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public double getDouble(long index) {
		throw new IndexOutOfBoundsException();
	}

	@Override
	public void putDouble(long index, double value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public byte get() {
		throw new BufferUnderflowException();
	}

	@Override
	public void put(byte b) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public short getShort() {
		throw new BufferUnderflowException();
	}

	@Override
	public void putShort(short value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public int getInt() {
		throw new BufferUnderflowException();
	}

	@Override
	public void putInt(int value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public long getLong() {
		throw new BufferUnderflowException();
	}

	@Override
	public void putLong(long value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public float getFloat() {
		throw new BufferUnderflowException();
	}

	@Override
	public void putFloat(float value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public double getDouble() {
		throw new BufferUnderflowException();
	}

	@Override
	public void putDouble(double value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public char getChar() {
		throw new BufferUnderflowException();
	}

	@Override
	public void putChar(char value) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void get(byte[] dst) {
		if(dst.length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void get(byte[] dst, int offset, int length) {
		if(length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void put(byte[] src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(byte[] src, int offset, int length) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void get(short[] dst) {
		if(dst.length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void get(short[] dst, int offset, int length) {
		if(length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void put(short[] src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(short[] src, int offset, int length) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void get(char[] dst) {
		if(dst.length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void get(char[] dst, int offset, int length) {
		if(length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void put(char[] src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(char[] src, int offset, int length) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void get(int[] dst) {
		if(dst.length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void get(int[] dst, int offset, int length) {
		if(length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void put(int[] src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(int[] src, int offset, int length) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void get(float[] dst) {
		if(dst.length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void get(float[] dst, int offset, int length) {
		if(length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void put(float[] src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(float[] src, int offset, int length) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void get(long[] dst) {
		if(dst.length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void get(long[] dst, int offset, int length) {
		if(length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void put(long[] src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(long[] src, int offset, int length) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void get(double[] dst) {
		if(dst.length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void get(double[] dst, int offset, int length) {
		if(length > 0)throw new BufferUnderflowException();
	}

	@Override
	public void put(double[] src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(double[] src, int offset, int length) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(BigBuffer src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void put(ByteBuffer src) {
		throw new ReadOnlyBufferException();
	}

	@Override
	public void destroy() {
	}

}
